<script lang="tsx">
import type { PropType, Ref } from 'vue';
import { computed, defineComponent, toRefs, unref } from 'vue';
import type { FormActionType, FormSchema } from '../types/form';
import type { TableActionType } from '@/components/Table';
import { Col, Form, FormProps, Select } from 'ant-design-vue';
import { componentMap } from '@/components/Form/src/componentMap';
import { isFunction } from '@/utils/is';
import { createPlaceholderMessage } from '@/components/Form/src/helper';
import { upperFirst } from 'lodash-es';
import { useI18n } from '@/hooks/web/useI18n';
import { DefaultOptionType } from 'ant-design-vue/lib/select';
import { useItemLabelWidth } from '@/components/Form/src/hooks/useLabelWidth';
import Icon from '@/components/Icon/Icon.vue';

export default defineComponent({
  name: 'AdvancedQueryComponent',
  inheritAttrs: false,
  props: {
    schema: {
      type: Object as PropType<FormSchema>,
      default: () => ({}),
    },
    allDefaultValues: {
      type: Object as PropType<Recordable>,
      default: () => ({}),
    },
    formProps: {
      type: Object as PropType<FormProps>,
      default: () => ({}),
    },
    formModel: {
      type: Object as PropType<Recordable>,
      default: () => ({}),
    },
    setQuerySchema: {
      type: Function as PropType<
        (value: Object, option: DefaultOptionType | DefaultOptionType[]) => void
      >,
      default: null,
    },
    setFormModel: {
      type: Function as PropType<
        (key: string, value: any, schema: FormSchema) => void
      >,
      default: null,
    },
    tableAction: {
      type: Object as PropType<TableActionType>,
    },
    formActionType: {
      type: Object as PropType<FormActionType>,
    },
  },
  emits: ['deleteField'],
  setup(props, { slots, emit }) {
    const { t } = useI18n();
    const { schema, formProps } = toRefs(props) as {
      schema: Ref<FormSchema>;
      formProps: Ref<FormProps>;
    };
    const itemLabelWidthProp = useItemLabelWidth(schema, formProps);

    const getValues = computed(() => {
      const { allDefaultValues, formModel, schema } = props;
      return {
        field: schema.field,
        model: formModel,
        values: {
          ...allDefaultValues,
          ...formModel,
        } as Recordable,
        schema: schema,
      };
    });

    const getComponentsProps = computed(() => {
      const { schema, tableAction, formModel, formActionType } = props;
      let { componentProps = {} } = schema;
      if (isFunction(componentProps)) {
        componentProps =
          componentProps({ schema, tableAction, formModel, formActionType }) ??
          {};
      }
      return componentProps as Recordable;
    });

    function renderComponent() {
      const {
        renderComponentContent,
        component,
        field,
        changeEvent = 'change',
        valueField,
      } = props.schema;
      const isCheck = component && ['Switch', 'Checkbox'].includes(component);

      const eventKey = `on${upperFirst(changeEvent)}`;

      const on = {
        [eventKey]: (...args: Nullable<Recordable>[]) => {
          const [e] = args;
          if (propsData[eventKey]) {
            propsData[eventKey](...args);
          }
          const target = e ? e.target : null;
          const value = target ? (isCheck ? target.checked : target.value) : e;
          props.setFormModel(field, value, props.schema);
        },
      };
      const Comp = componentMap.get(component) as ReturnType<
        typeof defineComponent
      >;

      const propsData: Recordable = {
        allowClear: true,
        getPopupContainer: (trigger: Element) => trigger.parentNode,
        ...unref(getComponentsProps),
      };

      const isCreatePlaceholder = !propsData.disabled;
      // RangePicker place is an array
      if (isCreatePlaceholder && component !== 'RangePicker' && component) {
        propsData.placeholder =
          unref(getComponentsProps)?.placeholder ||
          createPlaceholderMessage(component);
      }
      propsData.codeField = field;
      propsData.formValues = unref(getValues);

      const bindValue: Recordable = {
        [valueField || (isCheck ? 'checked' : 'value')]: props.formModel[field],
      };

      const compAttr: Recordable = {
        ...propsData,
        ...on,
        ...bindValue,
      };

      if (!renderComponentContent) {
        return <Comp {...compAttr} />;
      }
      const compSlot = isFunction(renderComponentContent)
        ? { ...renderComponentContent(unref(getValues)) }
        : {
            default: () => renderComponentContent,
          };
      return <Comp {...compAttr}>{compSlot}</Comp>;
    }

    function renderItem() {
      const { itemProps, field, suffix, component } = props.schema;
      const { labelCol, wrapperCol } = unref(itemLabelWidthProp);

      const getContent = () => {
        return renderComponent();
      };

      const showSuffix = !!suffix;
      const getSuffix = isFunction(suffix) ? suffix(unref(getValues)) : suffix;

      const getQueryType = () => {
        return (
          <Select
            style="width: 100px"
            value={schema.value.queryOption}
            options={schema.value.queryOptions}
            onChange={(e) => props.setQuerySchema(e, schema.value)}
          ></Select>
        );
      };
      const { label } = props.schema;
      console.log('red');
      const handleDelete = (field: string) => {
        emit('deleteField', field);
      };
      return (
        <Form.Item
          name={field}
          class={{ 'suffix-item': showSuffix }}
          {...(itemProps as Recordable)}
          label={label}
          labelCol={labelCol}
        >
          <div style="display:flex">
            <div style="flex:1;">
              <div style="display: flex">
                {getQueryType()}
                {getContent()}
                <div class="delete">
                  <Icon
                    icon="material-symbols:delete-outline"
                    color="red"
                    onClick={() => handleDelete(field)}
                  />
                </div>
              </div>
            </div>
            {showSuffix && <span class="suffix">{getSuffix}</span>}
          </div>
        </Form.Item>
      );
    }
    console.log('渲染');
    return () => {
      const { colProps = {}, component } = props.schema;
      if (!componentMap.has(component)) {
        return null;
      }
      const realColProps = { ...colProps };
      const values = unref(getValues);

      const getContent = () => {
        return renderItem();
      };

      return <Col {...realColProps}>{getContent()}</Col>;
    };
  },
});
</script>
<style lang="less" scoped>
.delete {
  cursor: pointer;
  display: flex;
  align-items: center;
  width: 40px;
  justify-content: center;
}
</style>
